package life.majiang.community.utils;


import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.nio.charset.Charset;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class HttpClientUtils {

    /**
     * httpclient执行get请求
     *
     * @param url
     * @param params
     * @return
     */
    public static String doGet(String url, Map<String, String> params) throws Exception{
        CloseableHttpClient httpClient = null;
        HttpGet httpGet = null;
        String result = "";
        CloseableHttpResponse httpResponse = null;
        try {
            // 创建httpclient
            httpClient = url.startsWith("https")?createSSLInsecureClient():HttpClients.createDefault();

            // 构建uri
            URIBuilder builder = new URIBuilder(url);

            // 构建参数
            if (params != null) {
                for (Map.Entry<String, String> param : params.entrySet()) {
                    builder.addParameter(param.getKey(), param.getValue());
                }
            }

            URI uri = builder.build();

            // 构建get请求
            httpGet = new HttpGet(uri);

            // 执行
            httpResponse = httpClient.execute(httpGet);

            result = EntityUtils.toString(httpResponse.getEntity(), Charset.defaultCharset());
        } catch (Exception e) {
            throw e;
        } finally {
            httpGet.releaseConnection();
            close(httpClient, httpResponse);
        }
        return result;
    }

    /**
     * 执行get请求没有参数
     *
     * @param url
     * @return
     */
    public static String doGet(String url)throws Exception {
        return doGet(url, null);
    }

    /**
     * 执行post请求
     *
     * @param url
     * @param params
     * @return
     */
    public static String doPost(String url, Map<String, String> params,Map<String,String> header) {
        CloseableHttpClient httpClient = null;
        HttpPost httpPost =  null;
        String result = "";
        CloseableHttpResponse httpResponse = null;
        try {

            // 创建httpclient
            httpClient = url.startsWith("https")?createSSLInsecureClient():HttpClients.createDefault();

            // 构建请求
            httpPost = new HttpPost(url);

            //构建请求头
            if(header!=null){
                for(Map.Entry<String,String> entry : header.entrySet()){
                      httpPost.addHeader(entry.getKey(), entry.getValue());
                }
            }

            // 构建参数
            if (params != null) {
                List<NameValuePair> paramList = new ArrayList<NameValuePair>();
                for (Map.Entry<String, String> param : params.entrySet()) {
                    paramList.add(new BasicNameValuePair(param.getKey(), param.getValue()));
                }

                // 模拟form表单entity
                UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(paramList, Charset.defaultCharset());
                httpPost.setEntity(formEntity);
            }

            // 执行
            httpResponse = httpClient.execute(httpPost);
            result = EntityUtils.toString(httpResponse.getEntity(), Charset.defaultCharset());

        } catch (Exception e) {

        } finally {
            httpPost.releaseConnection();
            close(httpClient, httpResponse);
        }
        return result;
    }

    /**
     * 执行post请求没有参数
     *
     * @param url
     * @return
     */
    public static String doPost(String url) {
        return doPost(url, null,null);
    }

    /**
     * 执行post请求，参数为json字符串
     *
     * @param url
     * @param jsonParam
     * @return
     */
    public static String doPostJsonParam(String url, String jsonParam)throws Exception {
        CloseableHttpClient httpClient = null;
        HttpPost httpPost = null;
        String result = "";
        CloseableHttpResponse httpResponse = null;
        try {
            // 创建httpclient
            httpClient = url.startsWith("https")?createSSLInsecureClient():HttpClients.createDefault();
            // 构建请求
            httpPost = new HttpPost(url);

            if (jsonParam!=null && !"".equals(jsonParam)) {
                // 创建请求实体
                StringEntity stringEntity = new StringEntity(jsonParam, ContentType.APPLICATION_JSON);
                httpPost.setEntity(stringEntity);
            }

            // 执行
            httpResponse = httpClient.execute(httpPost);
            result = EntityUtils.toString(httpResponse.getEntity(), Charset.defaultCharset());

        } catch (Exception e) {
            throw e;
        } finally {
            httpPost.releaseConnection();
            close(httpClient, httpResponse);
        }
        return result;
    }

    public static String doPostBodyData(String url, String bodyData)throws Exception {
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse httpResponse = null;
        HttpPost httpPost =  null;
        String result = "";
        try {
            // 创建httpclient
            httpClient = url.startsWith("https")?createSSLInsecureClient():HttpClients.createDefault();
            httpPost = new HttpPost(url);
            httpPost.setEntity(new StringEntity(bodyData, Charset.defaultCharset()));
            // 得到返回的response.
            httpResponse = httpClient.execute(httpPost);
            HttpEntity entity = httpResponse.getEntity();
            result =EntityUtils.toString(httpResponse.getEntity(), Charset.defaultCharset());
        } catch (Exception e) {
            throw e;
        } finally {
            httpPost.releaseConnection();
            close(httpClient,httpResponse);
        }
        return result;
    }

    /* 发送 post请求 用HTTPclient 发送请求*/
    public static byte[] doPostByte(String url, String json)throws Exception {

        CloseableHttpClient httpclient = null;
        CloseableHttpResponse response = null;
        HttpPost httppost = null;
        InputStream inputStream = null;
        byte[] data = null;

        try {
            // 创建默认的httpClient实例.
            httpclient = url.startsWith("https")?createSSLInsecureClient():HttpClients.createDefault();
            // 创建httppost
            httppost = new HttpPost(url);
            httppost.addHeader("Content-type", "application/json; charset=utf-8");
            httppost.setHeader("Accept", "application/json");
            StringEntity stringEntity = new StringEntity(json, Charset.forName("UTF-8"));
            stringEntity.setContentEncoding("UTF-8");
            httppost.setEntity(stringEntity);
            response = httpclient.execute(httppost);
            // 获取相应实体
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                inputStream = entity.getContent();
                data = readInputStream(inputStream);
            }

        } catch (Exception e) {
           throw e;
        } finally {
            httppost.releaseConnection();
            close(httpclient,response);
        }
        return data;
    }

    /**  将流 保存为数据数组
     * @param inStream
     * @return
     * @throws Exception
     */
    public static byte[] readInputStream(InputStream inStream) throws Exception {
        byte[]  bytes = null;
        ByteArrayOutputStream outStream = null;
        try {
            outStream = new ByteArrayOutputStream();
            // 创建一个Buffer字符串
            byte[] buffer = new byte[1024];
            // 每次读取的字符串长度，如果为-1，代表全部读取完毕
            int len = 0;
            // 使用一个输入流从buffer里把数据读取出来
            while ((len = inStream.read(buffer)) != -1) {
                // 用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度
                outStream.write(buffer, 0, len);
            }
            // 把outStream里的数据写入内存
            bytes = outStream.toByteArray();
        }catch (Exception e){
            throw e;
        }finally {
            // 关闭输入流
            inStream.close();
            outStream.close();
        }
        return bytes;
    }

    /**
     * 创建 SSL连接
     * @return
     * @throws Exception
     */
    private static CloseableHttpClient createSSLInsecureClient() throws Exception {
            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
                public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                    return true;
                }
            }).build();

                SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, new X509HostnameVerifier() {
                @Override
                public boolean verify(String arg0, SSLSession arg1) {
                    return true;
                }

                @Override
                public void verify(String host, SSLSocket ssl)
                        throws IOException {
                }

                @Override
                public void verify(String host, X509Certificate cert)
                        throws SSLException {
                }

                @Override
                public void verify(String host, String[] cns,
                                   String[] subjectAlts) throws SSLException {
                }
            });
            return HttpClients.custom().setSSLSocketFactory(sslsf).build();
    }

    /**
     * 关闭httpClient和httpResponse
     *
     * @param httpClient
     * @param httpResponse
     */
    private static void close(CloseableHttpClient httpClient, CloseableHttpResponse httpResponse) {
        if (httpResponse != null) {
            try {
                httpResponse.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (httpClient != null) {
            try {
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}